#pragma once

#include "d3d9.h"
#include "d3dx9.h"
#include <vector>
#include "ModelManager.h"

// Add pragma comments so you do not have to change
// the property dependencies
#pragma comment (lib, "d3d9.lib")
#pragma comment (lib, "d3dx9.lib")

struct s_TeslaCoil
{
	D3DXMATRIX	worldMat, scaleMat, rotMat, transMat;
	ID3DXMesh*			m_pMesh;
	ID3DXMesh*			m_pMesh2;
	D3DMATERIAL9*		m_pMaterials;
	D3DMATERIAL9*       m_pMaterials2;
	DWORD				m_dwNumMaterials;
	DWORD				m_dwNumMaterials2;
	LPDIRECT3DTEXTURE9*	m_pMeshTextures;
	LPDIRECT3DTEXTURE9* m_pMeshTextures2;
	D3DXVECTOR3			vecPos;
	D3DXVECTOR3			vecPos2;
	D3DXVECTOR3			vecRot;
	D3DXVECTOR3			vecScale;
	D3DXVECTOR3			vecScale2;
	// AABB members
	D3DXVECTOR3			vecBBMin;
	D3DXVECTOR3			vecBBMax;
	D3DXVECTOR3			vecModelBounds[8];
	D3DXVECTOR3			worldBBmin;
	D3DXVECTOR3			worldBBmax;
	bool				bCharged; // determines whether an electric charge is coming off of the tesla
	//short				sTimeCount;
};

struct s_AcidPit
{
	D3DXMATRIX	worldMat, worldMat2, scaleMat, rotMat, transMat;
	ID3DXMesh*			m_pMesh;
	ID3DXMesh*			m_pMesh2;
	D3DMATERIAL9*		m_pMaterials;
	D3DMATERIAL9*       m_pMaterials2;
	DWORD				m_dwNumMaterials;
	DWORD				m_dwNumMaterials2;
	LPDIRECT3DTEXTURE9*	m_pMeshTextures;
	LPDIRECT3DTEXTURE9* m_pMeshTextures2;
	D3DXVECTOR3			vecPos2;
	D3DXVECTOR3			vecPos;
	D3DXVECTOR3			vecRot;
	D3DXVECTOR3			vecScale;
	D3DXVECTOR3			vecScale2;
	// AABB members
	D3DXVECTOR3			vecBBMin;
	D3DXVECTOR3			vecBBMax;
	D3DXVECTOR3			vecModelBounds[8];
	D3DXVECTOR3			worldBBmin;
	D3DXVECTOR3			worldBBmax;
	// Behavioral Control Variables
	bool				bAcidSpray;
};

struct s_Piston
{
	D3DXMATRIX	worldMat, scaleMat, rotMat, transMat;
	ID3DXMesh*			m_pMesh;
	D3DMATERIAL9*		m_pMaterials;
	DWORD				m_dwNumMaterials;
	LPDIRECT3DTEXTURE9*	m_pMeshTextures;
	D3DXVECTOR3			vecPos;
	D3DXVECTOR3			vecRot;
	D3DXVECTOR3			vecSpeed;
	D3DXVECTOR3			vecScale;
	// AABB members
	D3DXVECTOR3			vecBBMin;
	D3DXVECTOR3			vecBBMax;
	D3DXVECTOR3			vecModelBounds[8];
	D3DXVECTOR3			worldBBmin;
	D3DXVECTOR3			worldBBmax;
	// action control variables
	float				fYMax;
	float				fYMin;
	bool				bMaxHeight;
};

struct s_Firewall
{
	D3DXMATRIX	worldMat, scaleMat, rotMat, transMat;
	ID3DXMesh*			m_pMesh;
	D3DMATERIAL9*		m_pMaterials;
	DWORD				m_dwNumMaterials;
	LPDIRECT3DTEXTURE9*	m_pMeshTextures;
	D3DXVECTOR3			vecPos;
	D3DXVECTOR3			vecRot;
	D3DXVECTOR3			vecScale;
	// AABB members
	D3DXVECTOR3			vecBBMin;
	D3DXVECTOR3			vecBBMax;
	D3DXVECTOR3			vecModelBounds[8];
	D3DXVECTOR3			worldBBmin;
	D3DXVECTOR3			worldBBmax;
};

class ObstacleManager
{
private:
	// Singleton instance
	static ObstacleManager*	m_ObstacleInstance;
	// Model index to traverse through the vector
	short				sObstacleIndex;
	short				sTeslaIndex;
	short				sAcidIndex;
	short				sPistonIndex;
	short				sFirewallIndex;
	// Pointer to the D3D Device
	IDirect3DDevice9*	m_Device;
	ModelManager*		modelMan;
	// Mesh to show the bounding box for testing purposes
	ID3DXMesh*			m_pBBTeslaMesh;
	ID3DXMesh*			m_pBBAcidMesh;
	ID3DXMesh*			m_pExtendedCollisionMesh;
	// timing variables to help control obstacle behaviors
	long				lStartTime;
	long				lCurrentTime;

public:
	ObstacleManager(void);
	~ObstacleManager(void);

	// Create the vector to hold the models
	std::vector<s_TeslaCoil*> teslaList;
	std::vector<s_AcidPit*> acidPitList;
	std::vector<s_Piston*> pistonList;
	std::vector<s_Firewall*> firewallList;

	// Singleton functions
	static ObstacleManager* GetInstance(void);
	void DeleteInstance(void);
	// Initializing the manager
	void InitObstacleManager(IDirect3DDevice9* m_pD3DDevice);
	// Load models
	//int CreateObstacle(LPCSTR xFileName, int iObstacleCount);
	short ReturnTeslaIndex(void);
	short ReturnAcidIndex(void);
	short ReturnPistonIndex(void);
	short ReturnFirewallIndex(void);
	short CreateTeslaCoil(D3DXVECTOR3 vecPos);
	short CreateAcidPit(D3DXVECTOR3 vecPos);
	short CreatePiston(D3DXVECTOR3 vecPos);
	short CreateFirewall(D3DXVECTOR3 vecPos);
	void Update(float deltaTime);
	// Drawing models
	void DrawModel(float deltaTime);
	void CalculateTeslaBB(short sObstacleID);
	bool TeslaCollision(short sObstacleID);
	void CalculateAcidBB(short sObstacleID);
	bool AcidCollision(short sObstacleID);
	void CalculatePistonBB(short sObstacleID);
	bool PistonCollision(short sObstacleID);
	void CalculateFirewallBB(short sObstacleID);
	bool FirewallCollision(short sObstacleID);
	bool FireWallLoop(void);
	void DestroyAllObstacles(void);
};
